/**
 * ArrayList represents an array implementation of a list. The front of
 * the list is kept at array index 0. This class will be extended
 * to create a specific kind of list.
 *
 * @author Dr. Lewis
 * @version 1.0, 04/19/2010
 */

package jss2;
import jss2.exceptions.*;

public class ArrayStack<T> implements StackADT<T>
{
    protected final int DEFAULT_CAPACITY = 100;
    protected int top;
    protected int size;
    private T[] stack;
    
    /**
     * Creates empty stack with default capacity.
     */
    public ArrayStack()
    {
	top = 0;
	size = 0;
	stack = (T[])(new Object[DEFAULT_CAPACITY]);
    }
   
    /**
    * Creates an empty list using the specified capacity.
    *
    * @param initialCapacity  the initial capacity of the list
    */
    public ArrayStack(int initialCapacity)
    {
	top = 0;
	stack = (T[])(new Object[initialCapacity]);
    }
   
    /**
     * Pushes element into the top of the stack.
     *
     * @param element the element neing pushed into the stack.
     *
     */
    public void push(T element)
    {
	if(size()==stack.length)
	    expandCapacity();
	
	size++;
	stack[top++]=element;
    }
   
    /**
    * Returns the array index of the top element and removes it
    * from the stack, or the stack is empty throws exception.
    *
    * @return        the element at the top of the stack.
    */
    public T pop() throws EmptyStackException
    {
	if(isEmpty())
	    throw new EmptyStackException("Error: Stack was empty during call to pop.");
	
	top--;
	size--;
	T result = stack[top];
	stack[top]=null;
	return result;
    }

    /**
    * Returns the array index of the top element without
    * removing it from the stack. If the stack is empty,
    * throw exception.
    *
    * @return        the element at the top of the stack.
    */
    public T peek() throws EmptyStackException
    {
	if(isEmpty())
	    throw new EmptyStackException("Error: Stack was empty during call to peek.");
	
	return stack[top-1];
    }

    /**
    * Returns true if this list is empty and false otherwise. 
    *
    * @return  true if this list is empty
    */
    public boolean isEmpty()
    {
	return (top == 0 ? true : false);
    }

   /**
    * Creates a new array to store the contents of the list with
    * twice the capacity of the old one.
    */
    public void expandCapacity()
    {
	T[] larger = (T[])(new Object[stack.length*2]);
	for(int index=0;index<stack.length;index++)
	    larger[index] = stack[index];

	stack=larger;
    }
    
   /**
    * Returns the number of elements currently in this list.
    *
    * @return  the integer number of elements in this list
    */
    public int size()
    {
	return size;
    }
    
   /**
    * Returns a string representation of this list. 
    *
    * @return  a string representation of this list
    */
    public String toString()
    {
	String result = "";

	for (int scan=size()-1; scan >= 0; scan--) 
	    result += stack[scan].toString() + "\n";

	result = result.substring(0,result.length()-1);
	return result;
    }
}
